package com.evan.review.handler;

/**
 * Handler机制详解文档
 * 
 * 本文档详细介绍了Android中Handler消息机制的原理、组成部分和底层实现
 * 适用于Android开发面试准备（特别是字节跳动抖音部门面试）
 */
public class HandlerDoc {

    /**
     * 一、Handler机制基础
     * 
     * 1. Handler被设计出来的原因
     *    - Android UI是线程不安全的，只能在主线程(UI线程)更新
     *    - 需要一种机制让子线程能够通知主线程更新UI
     *    - 提供一种线程间通信的标准机制，避免复杂的线程同步问题
     *    - 提供消息的调度和延时处理能力
     *    
     * 2. Handler机制的核心组成部分：
     *    - Handler: 发送和处理消息
     *    - Message: 消息实体
     *    - MessageQueue: 消息队列，存储待处理的消息
     *    - Looper: 循环从MessageQueue中取出消息并分发给Handler处理
     *    
     * 3. 子线程不能直接访问UI的原因：
     *    - Android的UI组件不是线程安全的，多线程并发访问可能导致UI状态不一致
     *    - UI操作必须在UI线程执行，确保UI操作的串行化处理，避免并发问题
     *    - ViewRootImpl的checkThread()方法会检查当前线程是否为UI线程
     *    
     * 4. 子线程访问UI的崩溃原因和解决方法：
     *    - 崩溃原因：ViewRootImpl.checkThread()方法会判断调用线程是否为UI线程，不是则抛出异常
     *    - 错误信息：CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views
     *    - 解决方法：
     *      a. 使用Activity.runOnUiThread(Runnable)
     *      b. 使用Handler发送消息到主线程
     *      c. 使用View.post(Runnable)方法
     *      d. 使用AsyncTask的onPostExecute回调
     */
    
    /**
     * 二、消息队列与消息分发
     * 
     * 1. MessageQueue的作用与实现：
     *    - MessageQueue是消息的存储容器，按照时间顺序管理Message
     *    - 底层数据结构：单链表(非Java集合类)，按照时间戳排序
     *    - 链表结构的优势：便于消息的插入和移除，尤其是延时消息的插入排序
     *    - 主要方法：enqueueMessage()和next()
     *    
     * 2. 延时消息的实现：
     *    - 消息中带有when字段，表示消息应该被处理的时间点(SystemClock.uptimeMillis() + delayMillis)
     *    - 入队时：根据when值插入到合适的位置(单链表的插入排序)
     *    - 出队时：判断队首消息的when是否到时间，未到则阻塞等待
     *    - 如果延时期间有新的更早的消息到来，会被唤醒重新计算等待时间
     *    
     * 3. 消息取出机制：
     *    - Looper.loop()方法中，循环调用MessageQueue.next()获取消息
     *    - next()方法是阻塞式的，没有消息或消息未到执行时间会阻塞线程
     *    - 阻塞基于Linux的epoll/管道机制实现
     *    
     * 4. 消息队列阻塞与唤醒：
     *    - 阻塞：没有消息或所有消息都未到执行时间，通过nativePollOnce()阻塞线程
     *    - 唤醒：有新消息入队或系统退出时通过nativeWake()唤醒线程
     *    - 底层原理：Linux的pipe/epoll机制
     *      a. 创建一个管道(pipe)，有读端和写端
     *      b. epoll监听读端的可读事件
     *      c. 阻塞：调用epoll_wait等待可读事件
     *      d. 唤醒：向写端写入数据，触发可读事件
     */

    /**
     * 三、同步屏障与异步消息
     * 
     * 1. 同步屏障(Sync Barrier)的概念：
     *    - 一种特殊的消息标记，用于阻挡同步消息，只让异步消息通过
     *    - 不会被分发处理，仅作为标记存在于消息队列中
     *    - 通过MessageQueue.postSyncBarrier()方法发送
     *    
     * 2. 同步屏障的实现原理：
     *    - 通过发送target为null的特殊Message实现
     *    - MessageQueue.next()方法会识别这种消息，跳过同步消息
     *    - 同步屏障存在时，只会返回异步消息
     *    
     * 3. 异步消息的实现：
     *    - 通过Message.setAsynchronous(true)将消息标记为异步
     *    - 异步消息不受同步屏障影响，即使有屏障依然能被处理
     *    
     * 4. 使用场景：
     *    - 用于UI绘制的优先级调度
     *    - Choreographer使用同步屏障确保vsync相关消息优先处理
     *    - UI更新中的动画、输入处理等高优先级任务
     *    - 系统关键服务的优先级保障
     */
    
    /**
     * 四、消息分发与回收
     * 
     * 1. 消息分发流程：
     *    - Looper.loop()方法中取出消息后，调用msg.target.dispatchMessage()
     *    - Handler.dispatchMessage()方法处理消息的优先级：
     *      a. 如果Message有callback(Runnable)，则执行它
     *      b. 如果Handler有mCallback，则调用mCallback.handleMessage()
     *      c. 调用Handler自身的handleMessage()方法
     *    
     * 2. Message的复用机制：
     *    - Message内部维护了一个消息池(静态链表sPool)
     *    - obtain()方法优先从消息池获取Message对象，避免频繁创建
     *    - recycle()方法回收Message到池中，清空消息内容
     *    - 消息池默认最大容量50(MAX_POOL_SIZE)
     *    - 典型的享元设计模式应用
     */
    
    /**
     * 五、Looper机制
     * 
     * 1. Looper的作用：
     *    - 为线程提供消息循环机制，循环从MessageQueue取出消息并分发
     *    - 管理线程与MessageQueue的关联
     *    - 提供线程消息循环的控制(quit/quitSafely)
     *    
     * 2. Looper与线程的关联：
     *    - 通过ThreadLocal机制实现线程与Looper的一对一绑定
     *    - prepare()方法为当前线程创建Looper并存入ThreadLocal
     *    - myLooper()方法获取当前线程的Looper
     *    
     * 3. ThreadLocal工作原理：
     *    - 每个Thread维护一个ThreadLocalMap实例
     *    - ThreadLocalMap使用ThreadLocal对象为key，存储线程私有的值
     *    - 优势：避免繁琐的线程参数传递，简化多线程设计
     *    - 弱引用实现，防止内存泄漏
     *    
     * 4. ThreadLocal的其他应用：
     *    - ActivityThread中的sCurrentActivityThread
     *    - LayoutInflater中的sLayoutInflaterFactory
     *    - Choreographer中的sThreadInstance
     *    - 各种数据库连接池、SimpleDateFormat线程安全处理
     *    
     * 5. Looper的创建与限制：
     *    - 一个线程只能创建一个Looper(prepare内部会判断)
     *    - quitAllowed参数决定Looper是否允许退出
     *    - 主线程的Looper在ActivityThread.main()中创建，quitAllowed=false
     */
    
    /**
     * 六、Handler进阶知识
     * 
     * 1. Looper.loop()死循环不会导致ANR的原因：
     *    - 系统设计：Android系统基于消息驱动，主线程就是要无限循环处理消息
     *    - CPU调度：当没有消息时，主线程通过nativePollOnce()进入休眠，不消耗CPU
     *    - 唤醒机制：有新消息到来时，线程被唤醒继续工作
     *    - 消息源头：系统服务通过Binder机制向主线程发送消息，触发各种生命周期回调
     *    
     * 2. Activity生命周期与消息循环：
     *    - Activity生命周期方法(onCreate/onStart等)由主线程Looper分发执行
     *    - ActivityThread内部的H类(继承Handler)接收来自AMS的生命周期事件
     *    - 消息类型如EXECUTE_TRANSACTION/LAUNCH_ACTIVITY等对应不同生命周期转换
     *    
     * 3. Message如何找到Handler：
     *    - Message持有发送它的Handler引用(target字段)
     *    - 在分发时，调用target.dispatchMessage(this)返回给原始Handler处理
     *    
     * 4. Handler的post与sendMessage区别：
     *    - post(Runnable)：将Runnable封装到Message的callback字段
     *    - sendMessage(Message)：直接发送消息对象
     *    - 本质上post内部也是创建Message并设置callback字段，然后sendMessage
     *    
     * 5. Handler.Callback机制：
     *    - 允许外部提供消息处理逻辑，无需继承Handler
     *    - 设计原则：组合优于继承，提高灵活性
     *    - 使用场景：需要拦截或修改Handler默认处理行为
     *    
     * 6. Handler与线程关系：
     *    - Handler、Looper、MessageQueue是一对一对一的关系
     *    - 线程与Looper是一对一关系，但线程可以有多个Handler
     *    - 多个Handler可以关联同一个Looper，共享同一个MessageQueue
     */
    
    /**
     * 七、Handler相关组件
     * 
     * 1. ActivityThread与Handler：
     *    - ActivityThread是Android应用的入口类，main()方法是入口点
     *    - main()中创建了主线程的Looper并调用loop()开始消息循环
     *    - 内部的H类(Handler子类)处理四大组件的生命周期消息
     *    - 因此主线程默认已有Looper，不需要手动prepare()和loop()
     *    
     * 2. IdleHandler机制：
     *    - MessageQueue提供的一种在队列空闲时执行任务的机制
     *    - 通过MessageQueue.addIdleHandler(IdleHandler)添加
     *    - 实现MessageQueue.IdleHandler接口的queueIdle()方法
     *    - 应用场景：
     *      a. 应用启动后的延迟初始化
     *      b. 页面显示后的预加载
     *      c. UI绘制完成后的操作
     *      d. 优化启动时间，分散任务执行
     *      有不同的方式 如只执行一次 或者 执行多次 
     *    
     * 3. HandlerThread：
     *    - 继承自Thread的便捷类，内部自动创建Looper
     *    - 简化了在子线程中使用Handler的流程
     *    - 特点：自带消息循环的线程，适合顺序处理后台任务
     *    - 应用场景：
     *      a. 网络请求/IO操作序列化处理
     *      b. 顺序处理图片/音频等资源
     *      c. IntentService的底层实现
     *    
     * 4. IntentService：
     *    - Service的子类，内部使用HandlerThread处理Intent请求
     *    - 特点：自动创建工作线程，处理完任务自动停止
     *    - 应用场景：
     *      a. 后台文件下载/上传
     *      b. 数据同步
     *      c. 定时任务
     *      d. 长时间运行但不需要用户交互的任务
     *    - 注意：在Android 11已被废弃，推荐使用WorkManager
     */
    
    /**
     * 八、Handler常见问题与优化
     * 
     * 1. BlockCanary原理（BlockCanary 是美团开源的Android平台卡顿监控组件，而LeakCanary是Square开源的内存泄漏检测组件）：
     *    - 基于Looper.loop()中的Printer机制
     *    - 在消息处理前后打印日志
     *    - 通过计算两次打印的时间差，检测主线程耗时操作
     *    - 核心实现：
     *      a. Looper.setMessageLogging(printer)设置监听
     *      b. 解析">>>>> Dispatching"和"<<<<< Finished"日志
     *      c. 时间差超阈值则记录堆栈、CPU、内存等信息
     *    
     * 2. Handler内存泄漏问题：
     *    - 原因：非静态内部类/匿名内部类持有外部类引用（非静态内部类/匿名内部类会隐式持有外部类）
     *          （非静态内部类/匿名内部类区别：非静态内部类可以访问外部类的成员变量和方法，而匿名内部类不能访问外部类的成员变量和方法
     *            而静态内部类不能访问外部类的成员变量和方法，只能访问静态变量和方法）
     *    - 当Handler有延迟消息，而Activity销毁时，Activity无法被回收
     *    - 解决方法：
     *      a. 使用静态内部类和WeakReference
     *      b. 在Activity.onDestroy()中调用Handler.removeCallbacksAndMessages(null)
     *      c. 使用LifecycleOwner自动管理Handler生命周期
     *    
     * 3. 利用Handler机制设计不崩溃的App：
     *    - 在ActivityThread的Looper之前设置全局异常处理器
     *    - Thread.setDefaultUncaughtExceptionHandler捕获所有未处理异常
     *    - 使用Handler发送异常信息到主线程，显示友好提示并重启应用
     *    - 注意：
     *      a. 生命周期方法中的异常无法完全拦截
     *      b. 需要区分可恢复和不可恢复的崩溃
     *      c. 合理记录崩溃信息，方便后续分析
     */
} 